package de.dhbw.karlsruhe.picsim.model.memory.impl;

import de.dhbw.karlsruhe.picsim.model.memory.CommandRegisterAddress;
import de.dhbw.karlsruhe.picsim.util.Bits;
import de.dhbw.karlsruhe.picsim.util.impl.BitUtilities;
import de.dhbw.karlsruhe.picsim.util.impl.Lengths;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public final class CommandRegisterAddressImpl implements CommandRegisterAddress {
    private final int value;
    private static final Log log = LogFactory.getLog(CommandRegisterAddressImpl.class);

    public CommandRegisterAddressImpl(final Bits value) {
        this(BitUtilities.fromLeastSignificantBitFirst(value));
    }

    /**
     * gibt auf jeden Fall eine Adresse zurück, auch wenn der Wert außerhalb des gültigen bereichs ist
     *
     * @param value Position im Befehlsregister
     * @return eine neue Adresse
     */
    @NotNull
    public static CommandRegisterAddress createUnSafe(final int value) {
        if (value >= 0 && value < Lengths.PROGRAM_MEMORY_SIZE) {
            return new CommandRegisterAddressImpl(value);
        }
        log.warn("illegal value" + value);
        return new CommandRegisterAddressImpl(value % Lengths.PROGRAM_MEMORY_SIZE);
    }


    @Nullable
    public static CommandRegisterAddress createSafe(final int value) {
        if (value >= 0 && value < Lengths.PROGRAM_MEMORY_SIZE) {
            return new CommandRegisterAddressImpl(value);
        }
        log.warn("illegal value" + value);
        return null;
    }

    private CommandRegisterAddressImpl(final int value) {
        this.value = value;
    }

    @Override
    public int asInteger() {
        return value;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final CommandRegisterAddressImpl that = (CommandRegisterAddressImpl) o;

        return value == that.value;

    }

    @Override
    public int hashCode() {
        return value;
    }

    @Override
    public String toString() {
        return "de.dhbw.karlsruhe.picsim.model.memory.impl.CommandRegisterAddressImpl{" +
                "value=" + value +
                '}';
    }
}
